/*
 * Copyright 2021 UltrasonicMadness
 * 
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

// Array of 256 bubbles
Bubble[] bubbles = new Bubble[256];

// The bubbles can be turned off.
boolean bubblesOn = true;

// Which stage the rainbow is at currently (0-1535, i.e. 256 * 6)
int rainbowFrame = 0;

// If true, hold on a steady color
boolean rainbowPaused = false;

// If true, generate rainbow-colored bubbles
boolean bubbleTeaMode = false;

void setup()
{
    size(800,600);
    noCursor();
    
    /*
     * Initialize the bubbles with a random x position, a y position
     * below the screen and a radius between 15 and 25 pixels.
     */
    for (int bubbleCounter = 0; bubbleCounter < bubbles.length; bubbleCounter++)
    {
        bubbles[bubbleCounter] = new Bubble(int(random(0, width)), height, int(random(15,25)), bubbleTeaMode);
    }
}

void draw()
{
    if (!rainbowPaused)
    {
        if (rainbowFrame >= 1535)
        {
            rainbowFrame = 0;
        }
        else
        {
            rainbowFrame++;
        }
    }
    
    genBackground();
    genRainbow(196);
    
    // Update each bubble
    for (int bubbleCounter = 0; bubbleCounter < bubbles.length; bubbleCounter++)
    {
        // Small chance of activating the bubble if the bubbles are on.
        if (int(random(0,64)) == 3 && bubblesOn)
        {
            bubbles[bubbleCounter].activate(bubbleTeaMode);
        }
      
        bubbles[bubbleCounter].advance();
        bubbles[bubbleCounter].draw();
    }
}

void genBackground()
{
    fill(255);
    noStroke();
    
    rect(0,0,width,height);
}

void genRainbow(int alpha)
{
    int counter = rainbowFrame % 256;
    int colorTransitionId = (rainbowFrame / 256) % 6;
    noStroke();
    
    switch (colorTransitionId)
    {
        case 0: // red to yellow, red at 255, green ascending, blue at 0
            fill(255, counter, 0, alpha);
            break;
      
        case 1: // yellow to green, red descending, green at 255, blue at 0
            fill(255 - counter, 255, 0, alpha);
            break;
      
        case 2: // green to cyan, red at 0, green at 255, blue ascending
            fill(0, 255, counter, alpha);
            break;
    
        case 3: // cyan to blue, red at 0, green descending, blue at 255
            fill(0, 255 - counter, 255, alpha);
            break;
    
        case 4: // blue to pink, red ascending, green at 0, blue at 255 
            fill(counter, 0, 255, alpha);
            break;
      
        case 5: // pink to red, red at 255, green at 0, blue descending 
            fill(255, 0, 255 - counter, alpha);
            break;
    }
  
    rect(0,0,width,height);
}

void keyPressed()
{
    switch (key)
    {
        case ' ':
            bubblesOn = !bubblesOn;
            break;
        
        case 'P':
        case 'p':
            rainbowPaused = !rainbowPaused;
            break;
        
        case 'T':
        case 't':
            bubbleTeaMode = !bubbleTeaMode;
            break;
        
        case '1':
            rainbowFrame = 0;
            break;
        
        case '2':
            rainbowFrame = 256;
            break;
        
        case '3':
            rainbowFrame = 512;
            break;
        
        case '4':
            rainbowFrame = 768;
            break;
        
        case '5':
            rainbowFrame = 1024;
            break;
        
        case '6':
            rainbowFrame = 1280;
            break;
    }
}
